const mqtt = require("mqtt");
const configManager = require("../utils/config-manager");
const logger = require("../utils/logger");

const SysConfig = configManager.getConfig();

// MQTT 连接配置
const MQTT_CONFIG = {
  options: {
    clientId: `electron-app-${Math.random().toString(16).slice(3)}`,
    clean: true,
    connectTimeout: 4000,
    reconnectPeriod: 1000,
    keepalive: 60,
  },
  // 重连配置
  reconnect: {
    maxRetries: 60 * 60 * 24, // 最大重试次数
    retryInterval: 1000 * 1, // 重试间隔（秒）
  },
};

class MQTTAPI {
  constructor() {
    this.client = null;
    this.connected = false;
    this.connecting = false;
    this.messageHandlers = new Map(); // 存储主题和对应的消息处理器
    this.connectionHandlers = []; // 连接状态变化处理器
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = MQTT_CONFIG.reconnect.maxRetries;
  }

  // 初始化MQTT服务
  async initialize() {
    try {
      // 检查是否有MQTT配置
      if (!SysConfig.mqtt) {
        logger.error(
          "MQTT---MQTT configuration missing, skipping MQTT initialization"
        );
        return;
      }

      // 连接MQTT服务器
      await this.connect();
    } catch (err) {
      logger.error("MQTT---Failed to initialize MQTT:", err);
      // 不抛出错误，让应用继续运行
    }
  }

  // 连接MQTT服务器
  connect() {
    return new Promise((resolve, reject) => {
      try {
        // 检查MQTT地址是否存在
        if (!SysConfig.mqtt) {
          logger.error("MQTT---No MQTT address configured");
          reject(new Error("No MQTT address configured"));
          return;
        }

        // 如果正在连接，直接返回
        if (this.connecting) {
          resolve();
          return;
        }

        this.connecting = true;
        logger.info("MQTT---Connecting to MQTT server:", SysConfig.mqtt);

        this.client = mqtt.connect(SysConfig.mqtt, MQTT_CONFIG.options);

        this.client.on("connect", () => {
          this.connected = true;
          this.connecting = false;
          this.reconnectAttempts = 0;
          logger.info("MQTT---Connected to MQTT server successfully");

          // 通知连接状态变化
          this.notifyConnectionChange(true);

          // 重新订阅之前的主题
          this.resubscribeTopics();

          resolve();
        });

        this.client.on("message", (topic, message) => {
          this.handleMessage(topic, message);
        });

        this.client.on("error", (err) => {
          this.connected = false;
          this.connecting = false;
          logger.error("MQTT---MQTT error:", err);
          this.notifyConnectionChange(false);
          reject(err);
        });

        this.client.on("close", () => {
          this.connected = false;
          this.connecting = false;
          logger.warn("MQTT---MQTT connection closed");
          this.notifyConnectionChange(false);
        });

        this.client.on("offline", () => {
          this.connected = false;
          this.connecting = false;
          logger.warn("MQTT---MQTT client offline");
          this.notifyConnectionChange(false);
        });

        this.client.on("reconnect", () => {
          this.reconnectAttempts++;
          logger.info(
            `MQTT---Reconnecting... Attempt ${this.reconnectAttempts}`
          );

          if (this.reconnectAttempts > this.maxReconnectAttempts) {
            logger.error("MQTT---Max reconnection attempts reached");
            this.client.end();
          }
        });

        // 设置连接超时
        setTimeout(() => {
          if (!this.connected && this.connecting) {
            this.connecting = false;
            reject(new Error("MQTT connection timeout"));
          }
        }, MQTT_CONFIG.options.connectTimeout);
      } catch (err) {
        this.connected = false;
        this.connecting = false;
        logger.error("MQTT---Failed to connect MQTT:", err);
        reject(err);
      }
    });
  }

  // 处理接收到的消息
  handleMessage(topic, message) {
    try {
      const handlers = this.messageHandlers.get(topic);
      if (handlers && handlers.length > 0) {
        const messageStr = message.toString();
        let parsedMessage;

        try {
          parsedMessage = JSON.parse(messageStr);
        } catch (e) {
          parsedMessage = messageStr;
        }

        logger.info(
          `MQTT---Received message on topic ${topic}:`,
          parsedMessage
        );

        // 调用所有注册的处理器
        handlers.forEach((handler) => {
          try {
            handler(topic, parsedMessage);
          } catch (err) {
            logger.error(
              `MQTT---Error in message handler for topic ${topic}:`,
              err
            );
          }
        });
      }
    } catch (err) {
      logger.error("MQTT---Error handling message:", err);
    }
  }

  // 注册消息处理器
  registerMessageHandler(topic, handler) {
    if (!this.messageHandlers.has(topic)) {
      this.messageHandlers.set(topic, []);
    }
    this.messageHandlers.get(topic).push(handler);
    logger.info(`MQTT---Registered message handler for topic: ${topic}`);
  }

  // 移除消息处理器
  removeMessageHandler(topic, handler = null) {
    if (handler) {
      // 移除特定的处理器
      const handlers = this.messageHandlers.get(topic);
      if (handlers) {
        const index = handlers.indexOf(handler);
        if (index > -1) {
          handlers.splice(index, 1);
          logger.info(
            `MQTT---Removed specific message handler for topic: ${topic}`
          );
        }
      }
    } else {
      // 移除所有处理器
      this.messageHandlers.delete(topic);
      logger.info(`MQTT---Removed all message handlers for topic: ${topic}`);
    }
  }

  // 重新订阅之前的主题
  resubscribeTopics() {
    const topics = Array.from(this.messageHandlers.keys());
    topics.forEach((topic) => {
      this.client.subscribe(topic, (err) => {
        if (err) {
          logger.error(`MQTT---Error resubscribing to topic ${topic}:`, err);
        } else {
          logger.info(`MQTT---Resubscribed to topic: ${topic}`);
        }
      });
    });
  }

  // 添加连接状态变化监听器
  onConnectionChange(handler) {
    this.connectionHandlers.push(handler);
  }

  // 移除连接状态变化监听器
  removeConnectionHandler(handler) {
    const index = this.connectionHandlers.indexOf(handler);
    if (index > -1) {
      this.connectionHandlers.splice(index, 1);
    }
  }

  // 通知连接状态变化
  notifyConnectionChange(connected) {
    this.connectionHandlers.forEach((handler) => {
      try {
        handler(connected);
      } catch (err) {
        logger.error("MQTT---Error in connection change handler:", err);
      }
    });
  }

  // 检查连接状态
  isConnected() {
    return this.connected;
  }

  // 发布消息
  publish(topic, message, options = {}) {
    return new Promise((resolve, reject) => {
      // 检查MQTT地址和连接状态
      if (!SysConfig.mqtt) {
        reject(new Error("No MQTT address configured"));
        return;
      }

      if (!this.client || !this.connected) {
        reject(new Error("MQTT client not connected"));
        return;
      }

      // 添加 QoS 配置
      const publishOptions = {
        qos: options.qos || 2, // 服务质量等级 2（Exactly Once）
        retain: options.retain || false, // 根据需要设置保留消息标志
      };

      const messageStr =
        typeof message === "string" ? message : JSON.stringify(message);

      logger.info(`MQTT---Publishing message to topic ${topic}:`, message);

      this.client.publish(topic, messageStr, publishOptions, (err) => {
        if (err) {
          logger.error("MQTT---Error publishing message:", err);
          reject(err);
          return;
        }
        logger.info(`MQTT---Message published successfully to topic: ${topic}`);
        resolve();
      });
    });
  }

  // 订阅主题
  subscribe(topic, handler) {
    return new Promise((resolve, reject) => {
      if (!this.client || !this.connected) {
        reject(new Error("MQTT client not connected"));
        return;
      }

      this.client.subscribe(topic, (err) => {
        if (err) {
          logger.error("MQTT---Subscribe error:", err);
          reject(err);
        } else {
          if (handler) {
            this.registerMessageHandler(topic, handler);
          }
          logger.info(`MQTT---Subscribed to topic: ${topic}`);
          resolve();
        }
      });
    });
  }

  // 取消订阅
  unsubscribe(topic) {
    return new Promise((resolve, reject) => {
      if (!this.client || !this.connected) {
        reject(new Error("MQTT client not connected"));
        return;
      }

      this.client.unsubscribe(topic, (err) => {
        if (err) {
          logger.error("MQTT---Unsubscribe error:", err);
          reject(err);
        } else {
          this.removeMessageHandler(topic);
          logger.info(`MQTT---Unsubscribed from topic: ${topic}`);
          resolve();
        }
      });
    });
  }

  // 断开连接
  disconnect() {
    return new Promise((resolve) => {
      if (this.client) {
        logger.info("MQTT---Disconnecting from MQTT server");
        this.client.end(true, {}, () => {
          this.client = null;
          this.connected = false;
          this.connecting = false;
          this.messageHandlers.clear();
          this.connectionHandlers = [];
          logger.info("MQTT---Disconnected from MQTT server");
          resolve();
        });
      } else {
        resolve();
      }
    });
  }

  // 获取当前订阅的主题列表
  getSubscribedTopics() {
    return Array.from(this.messageHandlers.keys());
  }

  // 获取连接状态信息
  getConnectionInfo() {
    return {
      connected: this.connected,
      connecting: this.connecting,
      reconnectAttempts: this.reconnectAttempts,
      subscribedTopics: this.getSubscribedTopics(),
      clientId: this.client ? this.client.options.clientId : null,
    };
  }
}

// 导出单例实例
const mqttApi = new MQTTAPI();
module.exports = mqttApi;
